package edu.gzhu.guli.back.service.course;

import java.util.Optional;

import org.modelmapper.ModelMapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import edu.gzhu.guli.core.common.ApplicationResult;
import edu.gzhu.guli.core.entity.Course;
import edu.gzhu.guli.core.entity.Course_;
import edu.gzhu.guli.core.entity.Subject;
import edu.gzhu.guli.core.entity.Teacher;
import edu.gzhu.guli.core.repository.CourseRepository;
import edu.gzhu.guli.core.repository.SubjectRepository;
import edu.gzhu.guli.core.repository.TeacherRepository;
import lombok.AllArgsConstructor;

@Service
@AllArgsConstructor
public class CourseService {
  final TeacherRepository teacherRepository;
  final CourseRepository courseRepository;
  final SubjectRepository subjectRepository;
  final ModelMapper modelMapper;

  public ApplicationResult<Page<CourseReadDto>> loadAllPage(int page, int size) {
    Page<Course> payload = courseRepository.findAll(PageRequest.of(page, size));
    Page<CourseReadDto> data = payload.map(it -> modelMapper.map(it, CourseReadDto.class));
    return ApplicationResult.succese(data);
  }

  public ApplicationResult<CourseReadDto> loadDetails(Long courseId) {
    Optional<Course> check = courseRepository.findById(courseId);
    if (!check.isPresent())
      return ApplicationResult.failure("未找到相应的课程");
    Course course = check.get();
    CourseReadDto data = modelMapper.map(course, CourseReadDto.class);
    return ApplicationResult.succese(data);
  }

  // 新建课程
  public ApplicationResult<CourseReadDto> create(CourseCreateOrEditDto dto) {
    Optional<Course> check = courseRepository
        .findOne(builder -> builder.andEquals(Course_.TITLE, dto.getTitle()).build());
    if (check.isPresent())
      return ApplicationResult.failure("课程名为：" + dto.getTitle() + "已存在");
    Course course = modelMapper.map(dto, Course.class);
    if (dto.getTeacherId() != null) {
      Optional<Teacher> checkTeacher = teacherRepository.findById(dto.getTeacherId());
      if (!checkTeacher.isPresent())
        return ApplicationResult.failure("未找到目标讲师");
      course.setTeacher(checkTeacher.get());
    }
    if (dto.getTopSubjectId() != null) {
      Optional<Subject> checkTopSubject = subjectRepository.findById(dto.getTopSubjectId());
      if (!checkTopSubject.isPresent())
        return ApplicationResult.failure("未找到目标父主题");
      course.setTopSubject(checkTopSubject.get());
      if (dto.getSubjectId() != null) {
        Optional<Subject> checkSubject = subjectRepository.findById(dto.getSubjectId());
        if (!checkSubject.isPresent() || !checkSubject.get().getPid().equals(checkTopSubject.get().getId()))
          return ApplicationResult.failure("未找到目标子主题");
        course.setSubject(checkSubject.get());
      }
    }
    course = courseRepository.save(course);
    CourseReadDto data = modelMapper.map(course, CourseReadDto.class);
    return ApplicationResult.succese(data);
  }

  // 编辑课程信息
  public ApplicationResult<CourseReadDto> edit(Long courseId, CourseCreateOrEditDto dto) {
    Optional<Course> check = courseRepository.findOne(builder -> builder
        .andNotEquals(Course_.ID, courseId)
        .andEquals(Course_.TITLE, dto.getTitle()).build());
    if (check.isPresent())
      return ApplicationResult.failure("课程名为：" + dto.getTitle() + "已存在");
    check = courseRepository.findById(courseId);
    if (!check.isPresent())
      return ApplicationResult.failure("未找到对应的课程");
    Course course = check.get();
    Course modifiedCourse = modelMapper.map(course, Course.class);
    modifiedCourse.setId(null);
    if (dto.getTeacherId() != null) {
      Optional<Teacher> checkTeacher = teacherRepository.findById(dto.getTeacherId());
      if (!checkTeacher.isPresent())
        return ApplicationResult.failure("未找到目标讲师");
      course.setTeacher(checkTeacher.get());
    } else {
      modifiedCourse.setTeacher(null);
    }
    if (dto.getTopSubjectId() != null) {
      Optional<Subject> checkTopSubject = subjectRepository.findById(dto.getTopSubjectId());
      if (!checkTopSubject.isPresent())
        return ApplicationResult.failure("未找到目标父主题");
      course.setTopSubject(checkTopSubject.get());
      if (dto.getSubjectId() != null) {
        Optional<Subject> checkSubject = subjectRepository.findById(dto.getSubjectId());
        if (!checkSubject.isPresent() || !checkSubject.get().getPid().equals(checkTopSubject.get().getId()))
          return ApplicationResult.failure("未找到目标子主题");
        course.setSubject(checkSubject.get());
      } else {
        modifiedCourse.setSubject(null);
      }
    } else {
      modifiedCourse.setTopSubject(null);
    }
    modifiedCourse = courseRepository.save(modifiedCourse);
    modelMapper.map(dto, modifiedCourse);
    CourseReadDto data = modelMapper.map(course, CourseReadDto.class);
    return ApplicationResult.succese(data);
  }

  // 删除课程
  public ApplicationResult<Object> delete(Long courseId) {
    return null;
  }

  // 绑定课程与讲师
  public ApplicationResult<Object> assignTeacher(Long teacherId, Long courseId) {
    Optional<Teacher> checkTeacher = teacherRepository.findById(teacherId);
    if (!checkTeacher.isPresent())
      return ApplicationResult.failure("未找到对应讲师");
    Optional<Course> checkCourse = courseRepository.findById(courseId);
    if (!checkCourse.isPresent())
      return ApplicationResult.failure("未找到对应课程");
    Teacher teacher = checkTeacher.get();
    Course course = checkCourse.get();
    course.setTeacher(teacher);
    courseRepository.save(course);
    return ApplicationResult.succese();
  }
}
